using System;
using System.Text;

namespace DownloadMailTask.POP3Client.Mime
{
    /// <summary>
    /// Summary description for Coding.
    /// </summary>
    public class QuotedCoding
    {
        /// <summary>
        /// zwraca tablice bajtow
        /// zamienia 3 znaki np '=A9' na odp wartosc.
        /// zamienia '_' na znak 32
        /// </summary>
        /// <param name="s">Kupis_Pawe=B3</param>
        /// <returns>Kupis Pawe?/returns>
        public static byte[] GetByteArray(string s)
        {
            byte[] buffer=new byte[s.Length];

            int bufferPosition=0;
            if (s.Length>1)
            {
                for(int i=0;i<s.Length;i++)
                {
                    if (s[i]=='=')
                    {
                        if (s[i+1]=='\r' && s[i+2]=='\n')
                            bufferPosition--;
                        else
                            buffer[bufferPosition]=System.Convert.ToByte(s.Substring(i+1,2),16);
                        i+=2;
                    }
                    else if (s[i]=='_')
                        buffer[bufferPosition]=32;
                    else
                        buffer[bufferPosition]=(byte)s[i];
                    bufferPosition++;
                }
            }
            else
            {
                buffer[bufferPosition]=32;
            }

            byte[] newArray=new byte[bufferPosition];
            Array.Copy(buffer,newArray,bufferPosition);
            return newArray;
        }

        /// <summary>
        /// Decoduje string "=?iso-8859-2?Q?Kupis_Pawe=B3?=" 
        /// lub zakodowany base64
        /// na poprawny
        /// </summary>
        /// <param name="s">"=?iso-8859-2?Q?Kupis_Pawe=B3?="</param>
        /// <returns>Kupis Pawe?/returns>
        public static string DecodeOne(string s)
        {
            char[] separator={'?'};
            string[] sArray=s.Split(separator);
            if (sArray[0].Equals("=")==false)
                return s;
			
            byte[] bArray;
            //rozpoznaj rodzj kodowania
            if (sArray[2].ToUpper()=="Q") //querystring
                bArray=GetByteArray(sArray[3]);
            else if (sArray[2].ToUpper()=="B")//base64
                bArray=Convert.FromBase64String(sArray[3]);
            else
                return s;
            //pobierz strone kodowa
            Encoding encoding=Encoding.GetEncoding(sArray[1]); 
            return encoding.GetString(bArray);
        }

        /// <summary>
        /// decoduje string zamienia wpisy (=?...?=) na odp wartosci
        /// </summary>
        /// <param name="s">"ala i =?iso-8859-2?Q?Kupis_Pawe=B3?= ma kota"</param>
        /// <returns>"ala i Pawe?Kupis ma kota"</returns>
        public static string Decode(string s)
        {
            StringBuilder retstring=new StringBuilder();
            int old=0,start=0,stop;
            for(;;)
            {
                start=s.IndexOf("=?",start);
                if (start==-1)
                {
                    retstring.Append(s,old,s.Length-old);
                    return retstring.ToString();
                }
                stop=s.IndexOf("?=",start+2);
                if (stop==-1) //blad w stringu
                    return s;
                retstring.Append(s,old,start-old);
                retstring.Append(DecodeOne(s.Substring(start,stop-start+2)));
                start=stop+2;
                old=stop+2;
            }
        }

    }
}